﻿#region Copyright © 2008 by Christian Rodemeyer
// $HeadURL: http://rodemeyer.googlecode.com/svn/trunk/Rodemeyer/Diagnostics/Dump.cs $
// $Revision: 26 $
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Threading;

namespace Rodemeyer.Diagnostics
{
    public static class Dump
    {

        public static void Exception(TextWriter w, Exception x)
        {
            if (x == null) return;
            Exception(w, x.InnerException);

            w.WriteLine("--- " + x.GetType().FullName + " ---");
            w.WriteLine(x.Message);
            w.WriteLine(x.StackTrace);
            w.WriteLine("==================");
            w.WriteLine();
        }

        public static string Exception(Exception x)
        {
            return ToString(delegate(TextWriter w) { Exception(w, x); });
        }

        public static void Assemblies(TextWriter w)
        {
            // Sorted list of running assemblies
            WriteHeader(w, "Loaded assemblies:");
            List<string> assemblies = new List<string>();
            int max_name_length = 0;
            int max_version_length = 0;
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
            {
                assemblies.Add(a.FullName);
                string[] sa = a.FullName.Split(',');
                max_name_length = Math.Max(sa[0].Length, max_name_length);
                max_version_length = Math.Max(sa[1].Length, max_version_length);
            }
            assemblies.Sort();
            string fmt = "{0," + -max_name_length + ("} {1," + -max_version_length + "} {2}");
            foreach (string s in assemblies)
            {
                string[] sa = s.Split(',');
                w.WriteLine(fmt, sa[0], sa[1], sa[2]);
            }
        }

        public static string Assemblies()
        { 
            return ToString(Assemblies);
        }

        public static void Dlls(TextWriter w)
        {
            WriteHeader(w, "Loaded dlls:");
            //int max_filename_length = 0;
            List<string> modules = new List<string>();
            foreach (ProcessModule module in Process.GetCurrentProcess().Modules)
            {
                //max_filename_length = Math.Max(max_filename_length, module.FileName.Length);
                modules.Add(module.FileName + " (" + module.FileVersionInfo.FileVersion + ")");
            }
            modules.Sort();
            //string fmt = "{0,-" + max_filename_length + "} {1}" + Environment.NewLine;
            foreach (string s in modules)
            {
                //                string[] sa = s.Split(',');
                //                report.AppendFormat(fmt, sa[0], sa[1]);
                w.WriteLine(s);
            }
        }

        public static string Dlls()
        {
            return ToString(Dlls);
        }

        //public static void Threads(TextWriter w)
        //{
        //    WriteHeader(w, "Running threads:");

        //    //Thread.GetDomain().DomainManager.
        //    //Process.GetCurrentProcess().Threads[0].
           
        //    //foreach (Thread t in Process.GetCurrentProcess().Threads)
        //    //{
        //    //    w.Write(t.ManagedThreadId + ": " + t.Name + " " + t.Priority);
        //    //    if (t.IsBackground) w.Write(" Background");
        //    //    if (t.IsThreadPoolThread) w.Write(" ThreadPool");
        //    //    w.Write(" " + t.ThreadState);
        //    //    w.WriteLine();
        //    //}
        //}

        //public static string Threads()
        //{
        //    return ToString(Threads);
        //}

        public static void Processes(TextWriter w)
        {
            WriteHeader(w, "Running processes:");
            foreach (Process p in Process.GetProcesses())
            {
                w.WriteLine(p.ProcessName + " from " + p.MainModule.FileName + "(" + p.MainModule.FileVersionInfo + ")");
                p.Dispose();
            }
        }

        public static string Processes()
        {
            return ToString(Processes);
        }

        public static void Environment(TextWriter w)
        {
            WriteHeader(w, "Environment:");
            w.WriteLine("User@Domain:  " + System.Environment.UserName + "@" + System.Environment.UserDomainName);
            w.WriteLine("Workstation:  " + System.Environment.MachineName);
            w.WriteLine("Timestamp:    " + DateTime.UtcNow.ToString("s"));
            w.WriteLine("Used Memory:  " + (System.Environment.WorkingSet / (1024 * 1024)) + "MB");
            w.WriteLine(".NET Version: " + System.Environment.Version);
            w.WriteLine("OS Version:   " + System.Environment.OSVersion);
        }
        
        public static string Environment()
        {
            return ToString(Environment);
        }

        static string ToString(Action<TextWriter> action)
        {
            StringWriter sw = new StringWriter();
            action(sw);
            return sw.ToString();
        }

        static void WriteHeader(TextWriter w, string header)
        {
            w.WriteLine();
            w.WriteLine(header);
            w.WriteLine(new string('-', header.Length)); 
        }


    }
}
